﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Shop.Intermediate;
using Shop.Intermediate.Data;
using Shop.Intermediate.Repository;
using DoNet.Common.Utilities;
using System.Data;

namespace Shop.Data.LinqToEntityProvider
{
    [Serializable]
    public class BasicDataRepository : IBasicDataRepository, IPageSplit
    {
        private ShopObjectContext m_context;

        public BasicDataRepository(ShopObjectContext context)
        {
            this.m_context = context;
        }

        public virtual void Create(IBasicData entity)
        {
            m_context.AddToBasicData(entity as BasicData);
        }

        public virtual void Update(IBasicData entity)
        {
            BasicData o1 = m_context.BasicData.FirstOrDefault(p => p.Code == entity.Code);
            m_context.ApplyPropertyChanges("BasicData", entity);
        }

        public virtual IBasicData GetEntity(string code)
        {
            object o = null;
            m_context.TryGetObjectByKey(new System.Data.EntityKey("ShopObjectContext.BasicData", "Code", code), out o);

            if (o == null)
                return null;
            return o as IBasicData;
        }

        public virtual void Delete(string code)
        {
            IBasicData dpt = new BasicData { Code = code };
            m_context.AttachTo("BasicData", dpt);
            m_context.DeleteObject(dpt);
        }

        public virtual IEnumerable<IBasicData> GetList()
        {
            IEnumerable<BasicData> query = from p in m_context.BasicData
                                           select p;
            return query.Cast<IBasicData>();
        }

        public virtual IEnumerable<IBasicData> GetList(string condition, object[] obj)
        {
            if (string.IsNullOrEmpty(condition) || obj.Length < 1)
            {
                return GetList();
            }

            IEnumerable<BasicData> query = (
                                             from p in m_context.BasicData
                                             select p
                                             )
                                             .Where(condition, obj);

            return query.Cast<IBasicData>();
        }

        public virtual IEnumerable<IBasicData> GetList(string condition, object[] whereObj, string ordering, object[] orderObj)
        {

            if (string.IsNullOrEmpty(ordering) || orderObj.Length < 1)
            {
                return GetList(condition, whereObj);
            }

            IEnumerable<BasicData> query;

            if (string.IsNullOrEmpty(condition) || ordering.Length < 1)
            {
                query = (
                        from p in m_context.BasicData
                        select p
                        )
                        .OrderBy(ordering, orderObj);
            }
            else
            {
                query = (
                         from p in m_context.BasicData
                         select p
                         )
                         .Where(condition, whereObj)
                         .OrderBy(ordering, orderObj);
            }

            return query.Cast<IBasicData>();
        }

        public virtual IEnumerable<IBasicData> GetList(int rownumber, string condition, object[] whereObj, string ordering, object[] orderObj)
        {
            if (string.IsNullOrEmpty(condition)||whereObj==null)
            {
                condition = "Code!=@0";
                whereObj = new object[] { "0"};
            }

            if (string.IsNullOrEmpty(ordering) || orderObj == null)
            {
                ordering = "Code";
                orderObj = new object[] { "ascending" };
            }

            IEnumerable<BasicData> query = (
                                            from p in m_context.BasicData
                                            select p
                                           )
                                           .Where(condition, whereObj)
                                           .OrderBy(ordering, orderObj)
                                           .Skip(0)
                                           .Take(rownumber);
            return query.Cast<IBasicData>();
        }

        public virtual IEnumerable<IBasicData> PageResultQuery<IBasicData>(string condition, object[] whereObj, string ordering, object[] orderObj, int pageNo, int pageSize, out int pageCount, out int recordCount)
        {
            IEnumerable<BasicData> query;

            if (string.IsNullOrEmpty(ordering) || orderObj.Length < 1)
            {
                if (string.IsNullOrEmpty(condition) || whereObj.Length < 1)
                {
                    recordCount = (
                                   from p in m_context.BasicData
                                   select p
                                   )
                                   .Count();
                    pageCount = recordCount / pageSize;
                    if (recordCount % pageSize > 0)
                    {
                        pageCount = pageCount + 1;
                    }
                    int startNum = (pageNo - 1) * pageSize;
                    query = (
                            from p in m_context.BasicData
                            select p
                            )
                            .Where(condition, whereObj)
                            .Skip(startNum)
                            .Take(pageSize);
                }
                else
                {
                    recordCount = (
                                    from p in m_context.BasicData
                                    select p
                                   )
                                   .Where(condition, whereObj)
                                   .Count();
                    pageCount = recordCount / pageSize;
                    if (recordCount % pageSize > 0)
                    {
                        pageCount = pageCount + 1;
                    }
                    int startNum = (pageNo - 1) * pageSize;
                    query = (
                              from p in m_context.BasicData
                              select p
                             )
                             .Where(condition, whereObj)
                             .Skip(startNum)
                             .Take(pageSize);
                }
            }
            else
            {
                if (string.IsNullOrEmpty(condition) || whereObj.Length < 1)
                {
                   recordCount = (
                                    from p in m_context.BasicData
                                    select p
                                   )
                                   .Count();

                    pageCount = recordCount / pageSize;

                    if (recordCount % pageSize > 0)
                    {
                        pageCount = pageCount + 1;
                    }

                    int startNum = (pageNo - 1) * pageSize;
                    
                    query = (
                            from p in m_context.BasicData
                            select p
                            )
                            .OrderBy(ordering, orderObj);
                }
                else
                {
                    recordCount = (
                                   from p in m_context.BasicData
                                   select p
                                  )
                                  .Where(condition,whereObj)
                                  .Count();

                    pageCount = recordCount / pageSize;

                    if (recordCount % pageSize > 0)
                    {
                        pageCount = pageCount + 1;
                    }

                    int startNum = (pageNo - 1) * pageSize;                  
                    
                    query = (
                             from p in m_context.BasicData
                             select p
                             )
                             .Where(condition, whereObj)
                             .OrderBy(ordering, orderObj);
                }
            }
            return query.Cast<IBasicData>();
        }

        public void SubmitChanges()
        {
            m_context.SaveChanges();
        }

    }
}
